/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package th.manager;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.wideplay.warp.persist.Transactional;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import th.dao.SmsDAO;
import th.model.Sms;
import th.stripes.Configuration;

/**
 *
 * @author fikri
 */
public class RetrieveSmsInfoManager {
    
    @Inject
    Provider<SessionFactory> sp;
    
    @Inject
    protected com.google.inject.Provider<Session> sessionProvider;
    
    private static Logger LOG = LoggerFactory.getLogger(RetrieveSmsInfoManager.class);
    
    private static final int TIMEOUT = 30 * 60 * 1000;
    
    private static String URL = "https://www.etracker.cc/mes/mes_dn.aspx";
    
    @Inject
    Configuration conf;
    
    @Inject private SmsDAO smsDAO;
    
    public void doStartRetrieve(Calendar cal) {
        LOG.debug("dostart");
        
        List<Sms> senaraiSms = doGetSenaraiSMS(cal);        
        
        if (!senaraiSms.isEmpty()) {
            doGetSmsInfo(senaraiSms);
        }
    }
    
    private List<Sms> doGetSenaraiSMS (Calendar cal) {
        
        StatelessSession ss = null;
        
        try {
            ss = sp.get().openStatelessSession();
       
            
            Criteria q = ss.createCriteria(Sms.class)
                    .add(Restrictions.gt("tarikhHantar", cal.getTime())  )
                    .add(Restrictions.isNull("deliveryNotification"));
            
            
            
            return q.list();
            
        }catch (Exception ex) {
            LOG.error("error ", ex);
        } finally {
            if (ss != null)
                ss.close();
        }
        return Collections.EMPTY_LIST;
    }
    
    private void doGetSmsInfo( List<Sms> senaraiSms ) {
        
        StatelessSession ss = null;
        Transaction tx = null;
        
        try {
            
            ss = sp.get().openStatelessSession();
            tx = ss.beginTransaction();
            
            for (Sms sms : senaraiSms) {
                
                StringBuilder cmd = new StringBuilder(URL)
                        .append("?phoneno=")
                        .append(sms.getNoTel())
                        .append("&mid=")
                        .append(sms.getMsisdn());

                HttpClient client = new HttpClient();
                GetMethod method = new GetMethod(cmd.toString());
                method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, TIMEOUT);
                method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                        new DefaultHttpMethodRetryHandler(3, false));

                client.executeMethod(method);
                BufferedReader rd = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
                String line = "";
                
                 while ((line = rd.readLine()) != null) {
                     
                     Criteria query = ss.createCriteria(Sms.class)
                            .add(Restrictions.eq("idSms", sms.getIdSms()));
                     
                     Sms s = (Sms) query.uniqueResult();
                     
                     String[] results = line.split(",");
                     if (results.length < 4) {
                        s.setDeliveryNotification("cannot retrieve");
                     } else {
                        String dn = StringUtils.isBlank(results[2]) ? "cannot retrieve" : results[2];
                        s.setDeliveryNotification(dn);
                                              
                     }
                     ss.update(s); 
                 }                
            }
            
            tx.commit();
                  
        } catch (Exception ex) {
            if (tx != null)
                tx.rollback();
            LOG.error(null, ex);
        } finally {
            if (ss != null) ss.close();            
        }
    }
    
    
    public List<Sms> getSenaraiSmsWithoutInfo(String tarikh) {
        
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        
        try {
            Date d = sdf.parse(tarikh);
            
            String query = "SELECT a FROM Sms a WHERE date(a.tarikhHantar) = :date and a.deliveryNotification is null";
        
            Query q = sessionProvider.get().createQuery(query).setParameter("date", d);
            
            return q.list();
            
        } catch (Exception ex) {
        }
        
        return Collections.EMPTY_LIST;
    }
    
    @Transactional
    public boolean doGetSmsInfoManual( List<Sms> senaraiSms ) {       
       
        
        try {
            for (Sms sms : senaraiSms) {
                
                LOG.debug("sms rekod {}", sms.getIdSms());
                StringBuilder cmd = new StringBuilder(URL)
                        .append("?phoneno=")
                        .append(sms.getNoTel())
                        .append("&mid=")
                        .append(sms.getMsisdn());

                HttpClient client = new HttpClient();
                GetMethod method = new GetMethod(cmd.toString());
                method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, TIMEOUT);
                method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                        new DefaultHttpMethodRetryHandler(3, false));

                client.executeMethod(method);
                BufferedReader rd = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
                String line = "";
                
                 while ((line = rd.readLine()) != null) {
                     
                     Sms s = smsDAO.findById(sms.getIdSms());                     
                     
                     String[] results = line.split(",");
                     if (results.length < 4) {
                        s.setDeliveryNotification("cannot retrieve");
                     } else {
                        String dn = StringUtils.isBlank(results[2]) ? "cannot retrieve" : results[2];
                        s.setDeliveryNotification(dn);
                                              
                     }
                     smsDAO.update(s);
                 }                
            }
                  
        } catch (Exception ex) {
            LOG.error("error", ex);
            return false;            
        }
        return true;
    }
    
    
    public static void main (String[] args) {
        
    }
    
}
